﻿using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Threading;

namespace SomethingSpacial.CustomControls
{
    /// <summary>
    /// ACP class inherits from APB and adds the layout system and layout behavior 
    /// as a panel to be used as needed.  this class is from the Crossfader project 
    /// on codeplex but has a number of incarnations based on that initial version.
    /// </summary>
    public class AnimatingCloudPanel : AnimatingPanelBase
    {
        private bool MyFirstTime = true;
        private int CloudBehavior = 1;

        private DispatcherTimer MyRollTimer;

        private List<int> ItemZIndex = new List<int>();
        private List<double> Positions = new List<double>();
        private List<double> PositionsX = new List<double>();
        private List<double> TransformThis = new List<double>();

        public bool IsInit = false;
        private double ThisMiddle = 300;
        public double ChildOffsetWidth = 280;
        public double PublicWidth = 600;
        public double PublicHeight = 600;
        public double LayoutTop = 100;

        public AnimatingCloudPanel()
        {
            AnimationCompleted += new RoutedEventHandler(RandomPanel_AnimationCompleted);
            this.Loaded += new RoutedEventHandler(AnimatingCloudPanel_Loaded);
        }

        void AnimatingCloudPanel_Loaded(object sender, RoutedEventArgs e)
        {
            // set ThisMiddle 
            if (ChildOffsetWidth == 0)
            {
                ChildOffsetWidth = 1;
            }
        }

        void RandomPanel_AnimationCompleted(object sender, RoutedEventArgs e)
        {
            MyFirstTime = true;

            MyRollTimer = new DispatcherTimer();
            MyRollTimer.Interval = TimeSpan.FromMilliseconds(10000);
            MyRollTimer.Tick += new EventHandler(MyRollTimerTick);
            MyRollTimer.Start();
        }

        public void RoleBack()
        {
            List<int> NewItemZIndex = new List<int>();
            List<double> NewPositions = new List<double>();
            List<double> NewPositionsX = new List<double>();
            List<double> NewTransformThis = new List<double>();

            for (int x = 0; x < this.Children.Count - 1; x++)
            {
                NewItemZIndex.Add(ItemZIndex[x + 1]);
                NewPositions.Add(Positions[x + 1]);
                NewPositionsX.Add(PositionsX[x + 1]);
                NewTransformThis.Add(TransformThis[x + 1]);
            }

            NewItemZIndex.Add(ItemZIndex[0]);
            NewPositions.Add(Positions[0]);
            NewPositionsX.Add(PositionsX[0]);
            NewTransformThis.Add(TransformThis[0]);

            ItemZIndex = NewItemZIndex;
            Positions = NewPositions;
            PositionsX = NewPositionsX;
            TransformThis = NewTransformThis;

            InvalidateArrange();
        }

        public void RoleForward()
        {
            List<int> NewItemZIndex = new List<int>();
            List<double> NewPositions = new List<double>();
            List<double> NewPositionsX = new List<double>();
            List<double> NewTransformThis = new List<double>();

            NewItemZIndex.Add(ItemZIndex[this.Children.Count - 1]);
            NewPositions.Add(Positions[this.Children.Count - 1]);
            NewPositionsX.Add(PositionsX[this.Children.Count - 1]);
            NewTransformThis.Add(TransformThis[this.Children.Count - 1]);

            for (int x = 0; x < this.Children.Count - 1; x++)
            {
                NewItemZIndex.Add(ItemZIndex[x]);
                NewPositions.Add(Positions[x]);
                NewPositionsX.Add(PositionsX[x]);
                NewTransformThis.Add(TransformThis[x]);
            }

            ItemZIndex = NewItemZIndex;
            Positions = NewPositions;
            PositionsX = NewPositionsX;
            TransformThis = NewTransformThis;

            InvalidateArrange();
        }

        //todo...?
        void MyRollTimerTick(object sender, EventArgs e)
        {
            //TODO: roll forward...
            MyRollTimer.Stop();
        }

        public void InitCollections()
        {
            ItemZIndex.Clear();
            //Opacities.Clear();
            Positions.Clear();
            PositionsX.Clear();
            TransformThis.Clear();

            int NewZIndex = 99;
            double NewOpacity = 1;
            double NewTransformThis = 1;

            // set max visable values.
            int MaxVisable = 3;
            MaxVisable = (this.Children.Count < MaxVisable) ? this.Children.Count : MaxVisable;

            for (int x = 0; x < this.Children.Count; x++)
            {
                if (x > 0)
                {
                    NewZIndex--;
                    NewOpacity = ((NewOpacity - .2) < 0) ? 0 : (NewOpacity - .4);
                    NewTransformThis = NewTransformThis - (NewTransformThis * .9);

                    // switch layout right and left...
                    if (x < MaxVisable)
                    {
                        if ((x % 2) == 0)
                        {
                            PositionsX.Add(0 - ( ChildOffsetWidth * .5));
                        }
                        else
                        {
                            PositionsX.Add(ThisMiddle + (ChildOffsetWidth * .9));
                        }
                    }
                    else
                    {
                        PositionsX.Add(ThisMiddle - ChildOffsetWidth);
                    }
                }
                else
                {
                    PositionsX.Add(ThisMiddle - ChildOffsetWidth);
                }

                ItemZIndex.Add(NewZIndex);
                //Opacities.Add(NewOpacity);
                TransformThis.Add(NewOpacity);

                // top layout...
                if (x < MaxVisable)
                {
                    if (x == 0)
                    {
                        Positions.Add(LayoutTop);
                    }
                    else
                    {
                        Positions.Add(LayoutTop / 2);
                    }
                }
                else
                {
                    Positions.Add(-1000);
                }
            }

            // change behavior from space to rotation...
            if (CloudBehavior == 1 && ItemZIndex.Count > 2)
            {
                int temp = ItemZIndex[0];
                ItemZIndex[0] = ItemZIndex[1];
                ItemZIndex[1] = temp;

                //double temp2 = Opacities[0];
                //Opacities[0] = Opacities[1];
                //Opacities[1] = temp2;

                double temp3 = Positions[0];
                Positions[0] = Positions[1];
                Positions[1] = temp3;

                double temp4 = PositionsX[0];
                PositionsX[0] = PositionsX[1];
                PositionsX[1] = temp4;

                double temp5 = TransformThis[0];
                TransformThis[0] = TransformThis[1];
                TransformThis[1] = temp5;
            }
        }

        protected override Size MeasureOverride(Size availableSize)
        {
            if (!IsInit)
            {
                IsInit = true;
                ThisMiddle = availableSize.Width / 2;

                PublicWidth = (availableSize.Width < 600) ? 600 : availableSize.Width;
                PublicWidth = (PublicWidth > 1000) ? PublicWidth - 100 : PublicWidth;

                PublicHeight = availableSize.Height;

                InitCollections();
            }

            for (int x = 0; x < this.Children.Count; x++)
            {
                this.Children[x].Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
            }
            return new Size();
        }

        protected override Size ArrangeOverride(Size FinalSize)
        {
            int x = 0;
            foreach (UIElement e in this.Children)
            {
                SetElementLocation(e, new Rect(PositionsX[x], Positions[x], this.DesiredSize.Width, e.DesiredSize.Height));

                e.SetValue(Canvas.ZIndexProperty, ItemZIndex[x]);

                if (e.GetType().ToString() == "SomethingSpacial.CustomControls.ContentControl")
                {
                    ((ContentControl)e).SetSizeTransform(TransformThis[x]);
                }

                x++;
            }

            if (MyFirstTime && this.Children.Count > 0)
            {
                MyFirstTime = false;
                this.InvalidateMeasure();
            }
            return FinalSize;
        }
    }
}
